package com.yixing.tech.entity.entity.attr;

import com.alibaba.fastjson.JSON;
import com.yixing.tech.common.base.BusinessException;
import com.yixing.tech.common.enums.ErrCode;
import com.yixing.tech.entity.entity.CustomActionParam;
import com.yixing.tech.entity.service.impl.ObjProcessor;
import com.yixing.tech.common.utils.CommonUtil;
import com.yixing.tech.common.utils.DataUtil;
import com.yixing.tech.common.vo.s5.EntitySchema;
import com.yixing.tech.entity.service.EntityBaseService;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.modelmapper.TypeToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * @author yixing tech
 * at 2021/10/9
 * describe：
 */
@Component
public final class UpdateEvent extends AttrType {

    @Resource
    private MongoTemplate mongoTemplate;
    @Resource
    private ObjProcessor objProcessor;
    @Autowired
    private EntityBaseService entityBaseService;
    private static UpdateEvent self;

    @PostConstruct
    private void init() {
        self = this;
    }

    public UpdateEvent() {
        super("关联更新", "updateEvent");
    }

    /**
     * 行为
     *
     * @param param
     */
    @Override
    public void exeAction(CustomActionParam param, List<EntitySchema.AttrVO> attrs) throws BusinessException {
        super.exeAction(param, attrs);
        String templateId = param.getObjCode();
        String entityId = param.getEntityId();
        String actionCode = param.getMethod();
        EntitySchema.AttrVO attr = self.objProcessor.getAttr(actionCode, attrs);
        Object ref = attr.getReference();
        if (CommonUtil.stringIsBlank(ref)) throw new BusinessException(ErrCode.MISS_CONFIG);
        EntitySchema.AttrVO.UpdateEventReference reference = (ref instanceof Map) ?DataUtil.o2o(ref, EntitySchema.AttrVO.UpdateEventReference.class):JSON.parseObject(ref.toString(), EntitySchema.AttrVO.UpdateEventReference.class);
        List<EntitySchema.AttrVO.BackReference> config = reference.getUpdateConfig();
        if (ObjectUtils.isEmpty(config)) throw new BusinessException(ErrCode.MISS_CONFIG);
        String updateList = reference.getUpdateList();
        Document document = self.entityBaseService.getEntity(templateId, entityId, null, false);
        if (document.getBoolean(actionCode, false)) return;
        /**
         * 批量更新
         */
        if (!CommonUtil.stringIsBlank(updateList)) {
            List<Document> updateObjs = document.getList(updateList, Document.class);
            if (!CommonUtil.listIsBlank(updateObjs)) {
                EntitySchema.AttrVO listAttr = self.objProcessor.getAttr(updateList, attrs);
                for (Document doc : updateObjs) {
                    document.put(updateList, doc);
                    List<EntitySchema.AttrVO> subAttrVOs = DataUtil.o2o(listAttr.getReference(), new TypeToken<List<EntitySchema.AttrVO>>() {
                    }.getType());
                    self.objProcessor.putRefValue(subAttrVOs, config, doc, null, false);
                }
            }
        } else {
            self.objProcessor.putRefValue(attrs, config, document, null, false);
        }
        Update update = new Update();
        update.set(actionCode, true);
        self.mongoTemplate.upsert(Query.query(Criteria.where("_id").is(new ObjectId(entityId))), update, "entity_" + templateId);
    }

}
